package netserver

import (
	"fmt"
	"iot-cloud-server/iotproto"
	"iot-cloud-server/mongodb"
	"net"
	"sync"

	"github.com/golang/protobuf/proto"
)

const (
	OK int32 = iota
	BAD_QUERY
	NO_MESSAGE
)

//net server relative
type context struct {
	svr *Svr
}

var ctx context

func (ctx *context) Init() error {
	fmt.Println("Init")
	return nil
}

func (ctx *context) Destroy() {
	fmt.Println("Destroy")
}

func (ctx *context) CheckInput(buf []byte) int64 {
	return int64(len(buf))
}

func (ctx *context) Process(pkg *Pkg, conn *net.TCPConn) error {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Process[E]", r)
		}
	}()
	var err error = nil
	var iRet int32 = OK
	for {
		queryReq := &iotproto.IOTQueryReq{}
		err = proto.Unmarshal(pkg.Req, queryReq)
		if err != nil {
			iRet = BAD_QUERY
			break
		}
		fmt.Println("queryReq:", queryReq)
		userDatas, err := ctx.svr.DB.QueryByTimeStamp(queryReq.GetTopic(), queryReq.GetTimeStamp())
		if err != nil {
			iRet = BAD_QUERY
			break
		}
		if len(userDatas) == 0 {
			iRet = NO_MESSAGE
			break
		}

		messages := make([]string, len(userDatas), len(userDatas))
		for i := 0; i < len(userDatas); i++ {
			messages[i] = userDatas[i].Message
		}
		queryRes := &iotproto.IOTQueryRes{
			ErrCode:      proto.Int32(OK),
			MessageSlice: messages,
		}
		resData, err := proto.Marshal(queryRes)
		if err != nil {
			iRet = BAD_QUERY
			break
		}
		iRet = OK
		conn.Write(resData)
		break
	}

	if err != nil {
		queryRes := &iotproto.IOTQueryRes{
			ErrCode:      proto.Int32(iRet),
			MessageSlice: nil,
		}
		resData, _ := proto.Marshal(queryRes)

		conn.Write(resData)
	}

	return nil
}

func NetServerRun(db *mongodb.MongoServer, wg *sync.WaitGroup) {
	var e error

	intf := []SvrIntf{
		SvrIntf{"tcp4", "127.0.0.1:17100"},
	}
	ctx.svr, e = NewSvr(db, wg, intf, &ctx, 20480, 50000)
	if e != nil {
		fmt.Println("NewSvr failed: %v", e)
		return
	}

	ctx.svr.Run()
}
